import { BaseScraper, type ScrapingResult } from './BaseScraper.js';
import { DataConverter, type ComponentData } from './DataConverter.js';
import type { CheerioAPI } from 'cheerio';

/**
 * Ant Design Charts 抓取器
 * 负责抓取 charts.ant.design 官网的图表组件数据
 */
export class AntDesignChartsScraper extends BaseScraper {
  private readonly chartsMap = new Map<string, string>([
    // 基础图表
    ['Line', '折线图'],
    ['Column', '柱状图'], 
    ['Bar', '条形图'],
    ['Area', '面积图'],
    ['Pie', '饼图'],
    ['Rose', '玫瑰图'],
    ['Scatter', '散点图'],
    ['Histogram', '直方图'],
    
    // 高级图表
    ['DualAxes', '双轴图'],
    ['Mix', '混合图表'],
    ['Facet', '分面图'],
    ['Sankey', '桑基图'],
    ['Sunburst', '旭日图'],
    ['Treemap', '矩形树图'],
    ['Waterfall', '瀑布图'],
    ['Funnel', '漏斗图'],
    
    // 统计图表
    ['Box', '箱型图'],
    ['Violin', '小提琴图'], 
    ['Heatmap', '热力图'],
    ['Density', '密度图'],
    ['RadialBar', '径向条形图'],
    ['Progress', '进度环图'],
    ['Gauge', '仪表盘'],
    ['Bullet', '子弹图'],
    
    // 关系图
    ['WordCloud', '词云图'],
    ['TinyLine', '迷你折线图'],
    ['TinyArea', '迷你面积图'],
    ['TinyColumn', '迷你柱状图'],
    ['RingProgress', '环形进度条'],
    
    // 地图类
    ['Choropleth', '填充地图'],
    ['Dot', '点地图'],
    ['Path', '路径地图'],
  ]);

  constructor() {
    super('AntDesignChartsScraper', 'https://ant-design-charts.antgroup.com');
  }

  /**
   * 执行抓取任务
   */
  async scrape(): Promise<ScrapingResult> {
    const startTime = Date.now();
    const result: ScrapingResult = {
      success: false,
      count: 0,
      data: [],
      errors: [],
      timestamp: new Date(),
      duration: 0,
    };

    try {
      this.log('🚀 开始抓取 Ant Design Charts 图表数据...');
      
      // 获取所有图表组件的URL列表
      const chartUrls = await this.getChartUrls();
      const totalCharts = chartUrls.length;
      
      this.emitProgress({
        stage: '获取图表列表',
        current: 0,
        total: 100,
        message: `发现 ${totalCharts} 个图表组件`,
      });

      const charts: ComponentData[] = [];

      // 抓取每个图表的详细信息
      for (let i = 0; i < chartUrls.length; i++) {
        const chartUrl = chartUrls[i];
        if (!chartUrl) continue;
        
        this.emitProgress({
          stage: '抓取图表详情',
          current: i + 1,
          total: chartUrls.length,
          item: chartUrl.name,
          message: `正在抓取 ${chartUrl.name}...`,
        });

        try {
          const chartData = await this.scrapeChart(chartUrl);
          if (chartData) {
            charts.push(chartData);
            this.log(`✅ 成功抓取: ${chartData.name}`);
          }
        } catch (error) {
          const errorMsg = `抓取图表 ${chartUrl.name} 失败: ${error instanceof Error ? error.message : String(error)}`;
          result.errors.push(errorMsg);
          this.error(errorMsg);
        }

        // 遵守速率限制
        await this.delay(this.rateLimitDelay);
      }

      result.data = charts;
      result.count = charts.length;
      result.success = true;
      
      this.log(`🎉 抓取完成! 成功收集 ${charts.length} 个图表组件`);

    } catch (error) {
      const errorMsg = `抓取过程发生错误: ${error instanceof Error ? error.message : String(error)}`;
      result.errors.push(errorMsg);
      this.error(errorMsg);
    }

    result.duration = Date.now() - startTime;
    return result;
  }

  /**
   * 获取所有图表组件的URL列表
   */
  private async getChartUrls(): Promise<Array<{ name: string; url: string; category: string }>> {
    const chartUrls: Array<{ name: string; url: string; category: string }> = [];

    try {
      // 从预定义的图表映射中构建URL列表
      for (const [chartName, category] of this.chartsMap.entries()) {
        const url = `/en/examples/${chartName.toLowerCase()}`;
        chartUrls.push({
          name: chartName,
          url: url,
          category: this.getCategoryFromDescription(category)
        });
      }

      // 也可以尝试从官网动态抓取图表列表
      try {
        const dynamicCharts = await this.scrapeDynamicChartList();
        for (const chart of dynamicCharts) {
          // 避免重复添加
          if (!chartUrls.find(c => c.name === chart.name)) {
            chartUrls.push(chart);
          }
        }
      } catch (error) {
        this.warn(`动态抓取图表列表失败: ${error instanceof Error ? error.message : String(error)}`);
      }

      this.log(`📋 发现 ${chartUrls.length} 个图表组件`);
      return chartUrls;

    } catch (error) {
      this.error(`获取图表URL列表失败: ${error instanceof Error ? error.message : String(error)}`);
      return [];
    }
  }

  /**
   * 动态抓取图表列表
   */
  private async scrapeDynamicChartList(): Promise<Array<{ name: string; url: string; category: string }>> {
    const chartUrls: Array<{ name: string; url: string; category: string }> = [];

    try {
      const html = await this.fetchPage('/en/examples');
      const $ = this.parseHtml(html);

      // 查找图表链接
      $('a[href*="/examples/"]').each((_, element) => {
        const $link = $(element);
        const href = $link.attr('href');
        const text = this.cleanText($link.text());
        
        if (href && text && href !== '/examples') {
          const chartName = this.extractChartName(href);
          if (chartName && text) {
            chartUrls.push({
              name: chartName,
              url: href,
              category: '图表组件'
            });
          }
        }
      });

      return chartUrls;
    } catch (error) {
      this.warn(`动态抓取失败: ${error instanceof Error ? error.message : String(error)}`);
      return [];
    }
  }

  /**
   * 抓取单个图表的详细信息
   */
  private async scrapeChart(chartInfo: { name: string; url: string; category: string }): Promise<ComponentData | null> {
    try {
      const html = await this.fetchPage(chartInfo.url);
      const $ = this.parseHtml(html);

      // 提取图表基本信息
      const title = this.extractTitle($) || chartInfo.name;
      const description = this.extractDescription($, chartInfo.name) || DataConverter.generateDefaultDescription(chartInfo.name, chartInfo.category);
      
      // 提取API文档
      const props = this.extractChartProps($, chartInfo.name);
      const examples = this.extractChartExamples($, chartInfo.name);
      const imports = this.generateChartImports(chartInfo.name);

      const chartData: ComponentData = {
        name: chartInfo.name,
        category: chartInfo.category,
        title: title,
        description: description,
        documentation_url: this.normalizeUrl(chartInfo.url),
        api_reference: this.normalizeUrl(`/zh/docs/api/${chartInfo.name.toLowerCase()}`),
        version: '2.x',
        tags: this.generateChartTags(chartInfo),
        props,
        examples,
        imports,
      };

      // 验证并修复数据完整性
      const validation = DataConverter.validateAndFixComponent(chartData);
      if (!validation.valid) {
        this.error(`图表 ${chartInfo.name} 数据无效: ${validation.errors.join(', ')}`);
        return null;
      }

      // 使用修复后的数据
      const fixedChartData = validation.fixedData;
      
      // 如果描述被修复了，记录日志
      if (chartData.description !== fixedChartData.description) {
        this.log(`🔧 图表 ${chartInfo.name} 描述已自动修复: "${fixedChartData.description}"`);
      }

      return fixedChartData;

    } catch (error) {
      this.error(`抓取图表 ${chartInfo.name} 失败: ${error instanceof Error ? error.message : String(error)}`);
      return null;
    }
  }

  /**
   * 提取图表标题
   */
  private extractTitle($: CheerioAPI): string {
    const selectors = [
      'h1',
      '.chart-title',
      '[data-testid="chart-title"]',
      '.demo-title'
    ];

    for (const selector of selectors) {
      const title = $(selector).first().text();
      if (title) {
        const cleanTitle = this.cleanText(title);
        if (cleanTitle) {
          return cleanTitle.split(' ')[0] || '';
        }
      }
    }

    return '';
  }

  /**
   * 提取图表描述
   */
  private extractDescription($: CheerioAPI, chartName: string): string {
    const selectors = [
      '.chart-description',
      '.demo-description',
      'h1 + p',
      '.markdown > p:first',
      'p:contains("图")',
      'p:contains("chart")'
    ];

    for (const selector of selectors) {
      const desc = $(selector).text();
      if (desc && desc.length > 10) {
        return this.cleanText(desc);
      }
    }

    // 如果没有找到描述，使用默认描述
    return this.getDefaultChartDescription(chartName);
  }

  /**
   * 提取图表属性
   */
  private extractChartProps($: CheerioAPI, chartName: string): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    const props: Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> = [];

    // 添加通用图表属性
    const commonProps = this.getCommonChartProps();
    props.push(...commonProps);

    // 添加特定图表属性
    const specificProps = this.getSpecificChartProps(chartName);
    props.push(...specificProps);

    // 尝试从页面提取API信息
    try {
      $('table tr').each((_, row) => {
        const $row = $(row);
        const cells = $row.find('td');
        
        if (cells.length >= 3) {
          const name = this.cleanText($(cells[0]).text());
          const type = this.cleanText($(cells[1]).text());
          const description = this.cleanText($(cells[2]).text());
          
          if (name && type) {
            props.push({
              name,
              type,
              required: false,
              description: description || `${name} 属性`,
            });
          }
        }
      });
    } catch (error) {
      this.warn(`提取 ${chartName} 属性失败: ${error instanceof Error ? error.message : String(error)}`);
    }

    return props;
  }

  /**
   * 提取图表示例
   */
  private extractChartExamples($: CheerioAPI, chartName: string): Array<{ title: string; code: string; description?: string }> {
    const examples: Array<{ title: string; code: string; description?: string }> = [];

    // 尝试从页面提取代码示例
    $('pre code, .highlight code').each((_, element) => {
      const code = $(element).text();
      if (code && code.length > 50 && code.includes(chartName)) {
        examples.push({
          title: `${chartName} 基础用法`,
          code: DataConverter.formatCode(code),
          description: `${chartName} 的基础使用示例`,
        });
      }
    });

    // 如果没有找到示例，生成默认示例
    if (examples.length === 0) {
      const defaultExample = this.generateDefaultChartExample(chartName);
      if (defaultExample) {
        examples.push(defaultExample);
      }
    }

    return examples;
  }

  /**
   * 生成图表导入信息
   */
  private generateChartImports(chartName: string): Array<{ import_path: string; import_name: string; is_default: boolean }> {
    return [
      {
        import_path: '@ant-design/charts',
        import_name: chartName,
        is_default: false,
      },
      {
        import_path: 'react',
        import_name: 'React',
        is_default: true,
      },
    ];
  }

  /**
   * 生成图表标签
   */
  private generateChartTags(chartInfo: { name: string; category: string }): string[] {
    const tags = new Set<string>();
    
    tags.add('charts');
    tags.add('visualization');
    tags.add('数据可视化');
    tags.add(chartInfo.category.toLowerCase());
    
    const name = chartInfo.name.toLowerCase();
    if (name.includes('line')) tags.add('折线图');
    if (name.includes('bar') || name.includes('column')) tags.add('柱状图');
    if (name.includes('pie')) tags.add('饼图');
    if (name.includes('area')) tags.add('面积图');
    if (name.includes('scatter')) tags.add('散点图');
    if (name.includes('gauge')) tags.add('仪表盘');
    if (name.includes('progress')) tags.add('进度图');
    if (name.includes('tiny')) tags.add('迷你图表');
    
    return Array.from(tags);
  }

  /**
   * 获取通用图表属性
   */
  private getCommonChartProps(): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    return [
      {
        name: 'data',
        type: 'any[]',
        required: true,
        description: '图表数据源',
      },
      {
        name: 'width',
        type: 'number',
        required: false,
        description: '图表宽度',
      },
      {
        name: 'height',
        type: 'number',
        required: false,
        description: '图表高度',
      },
      {
        name: 'autoFit',
        type: 'boolean',
        required: false,
        default_value: 'true',
        description: '是否自适应容器大小',
      },
      {
        name: 'theme',
        type: 'string | object',
        required: false,
        description: '图表主题',
      },
    ];
  }

  /**
   * 获取特定图表属性
   */
  private getSpecificChartProps(chartName: string): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    const specificProps: { [key: string]: any[] } = {
      'Line': [
        { name: 'xField', type: 'string', required: true, description: 'x轴字段' },
        { name: 'yField', type: 'string', required: true, description: 'y轴字段' },
        { name: 'seriesField', type: 'string', required: false, description: '分组字段' },
      ],
      'Column': [
        { name: 'xField', type: 'string', required: true, description: 'x轴字段' },
        { name: 'yField', type: 'string', required: true, description: 'y轴字段' },
        { name: 'seriesField', type: 'string', required: false, description: '分组字段' },
      ],
      'Pie': [
        { name: 'angleField', type: 'string', required: true, description: '角度字段' },
        { name: 'colorField', type: 'string', required: true, description: '颜色字段' },
        { name: 'radius', type: 'number', required: false, description: '饼图半径' },
      ],
      'Gauge': [
        { name: 'percent', type: 'number', required: true, description: '百分比值' },
        { name: 'range', type: 'object', required: false, description: '值域范围' },
      ],
    };

    return specificProps[chartName] || [];
  }

  /**
   * 获取默认图表描述
   */
  private getDefaultChartDescription(chartName: string): string {
    const descriptions: { [key: string]: string } = {
      'Line': '折线图，用于显示数据在连续时间间隔内的变化趋势',
      'Column': '柱状图，通过柱子的高度来表现数据的大小',
      'Bar': '条形图，通过条形的长度来表现数据的大小',
      'Area': '面积图，用于强调数量随时间而变化的程度',
      'Pie': '饼图，用于表示不同分类的占比情况',
      'Rose': '玫瑰图，饼图的变形，通过半径大小表示数据值',
      'Scatter': '散点图，用于观察两个变量之间的关系',
      'Gauge': '仪表盘，用于展示单个指标的进度或完成度',
      'Progress': '进度环图，用于显示任务完成进度',
      'Waterfall': '瀑布图，用于理解数据的累计效应',
      'Funnel': '漏斗图，用于业务流程分析',
      'Heatmap': '热力图，通过颜色变化来展示数据的分布',
      'WordCloud': '词云图，用于文本数据的可视化展示',
    };

    return descriptions[chartName] || `${chartName} - Ant Design Charts 图表组件`;
  }

  /**
   * 生成默认图表示例
   */
  private generateDefaultChartExample(chartName: string): { title: string; code: string; description?: string } | null {
    const examples: { [key: string]: string } = {
      'Line': `import { Line } from '@ant-design/charts';

const data = [
  { year: '2010', value: 3 },
  { year: '2011', value: 4 },
  { year: '2012', value: 3.5 },
  { year: '2013', value: 5 },
  { year: '2014', value: 4.9 },
];

const config = {
  data,
  xField: 'year',
  yField: 'value',
  height: 400,
};

export default () => <Line {...config} />;`,

      'Column': `import { Column } from '@ant-design/charts';

const data = [
  { type: '家具家电', sales: 38 },
  { type: '粮油副食', sales: 52 },
  { type: '生鲜水果', sales: 61 },
  { type: '美容洗护', sales: 145 },
];

const config = {
  data,
  xField: 'type',
  yField: 'sales',
  height: 400,
};

export default () => <Column {...config} />;`,

      'Pie': `import { Pie } from '@ant-design/charts';

const data = [
  { type: '分类一', value: 27 },
  { type: '分类二', value: 25 },
  { type: '分类三', value: 18 },
  { type: '分类四', value: 15 },
  { type: '其他', value: 10 },
];

const config = {
  data,
  angleField: 'value',
  colorField: 'type',
  radius: 0.8,
  height: 400,
};

export default () => <Pie {...config} />;`,
    };

    const code = examples[chartName];
    if (code) {
      return {
        title: `${chartName} 基础用法`,
        code: code,
        description: `${chartName} 图表的基础使用示例`,
      };
    }

    return null;
  }

  /**
   * 从URL中提取图表名称
   */
  private extractChartName(url: string): string {
    const match = url.match(/\/examples\/([^\/\?]+)/);
    if (match && match[1]) {
      // 将kebab-case转换为PascalCase
      return match[1]
        .split('-')
        .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))
        .join('');
    }
    return '';
  }

  /**
   * 根据描述获取分类
   */
  private getCategoryFromDescription(description: string): string {
    if (description.includes('基础') || description.includes('折线') || description.includes('柱状') || description.includes('饼图') || description.includes('面积')) {
      return '基础图表';
    }
    if (description.includes('高级') || description.includes('双轴') || description.includes('混合') || description.includes('桑基') || description.includes('旭日')) {
      return '高级图表';
    }
    if (description.includes('统计') || description.includes('箱型') || description.includes('热力') || description.includes('密度')) {
      return '统计图表';
    }
    if (description.includes('迷你') || description.includes('进度') || description.includes('小')) {
      return '迷你图表';
    }
    if (description.includes('地图')) {
      return '地图图表';
    }
    return '图表组件';
  }
}